package com.cncytech.uiautomator_demo;

import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;

import android.Manifest;
import android.app.Instrumentation;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.util.Log;

import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.test.filters.SdkSuppress;
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.Configurator;
import androidx.test.uiautomator.UiDevice;
import androidx.test.uiautomator.Until;

import com.cncytech.uiautomator_demo.IRunner;
import com.cncytech.uiautomator_demo.page.MainPage;
import com.cncytech.uiautomator_demo.page.SettingPage;
import com.cncytech.uiautomator_demo.policyinterface.impl.HardwareModuleManagement;
import com.cncytech.uiautomator_demo.policyinterface.impl.HardwareModuleManagementImpl;
import com.cncytech.uiautomator_demo.policyinterface.impl.TerminalBasicFunctionManagement;
import com.cncytech.uiautomator_demo.policyinterface.impl.TerminalBasicFunctionManagementImpl;
import com.cncytech.uiautomator_demo.proxy.ModuleProxy;
import com.cncytech.uiautomator_demo.utils.StreamGobbler;

import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;

import java.io.IOException;
import java.util.Objects;

import ga.mdm.PolicyManager;

/**
 * Instrumented test, which will execute on an Android device.
 *
 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 */
@RunWith(IRunner.class)
@SdkSuppress(minSdkVersion = 18)
public class BaseTest {
    private static final String TAG = "ExampleInstrumentedTest";
    private static final String BASIC_SAMPLE_PACKAGE = "com.cncytech.uiautomator_demo";
    private static final int LAUNCH_TIMEOUT = 5000;
    private static final String STRING_TO_BE_TYPED = "UiAutomator";
    protected final Context applicationContext = getApplicationContext();
    protected static UiDevice mDevice;
    protected static HardwareModuleManagement hmm;
    protected static TerminalBasicFunctionManagement tm;
    protected static MainPage mainPage;
    protected static SettingPage settingPage;




    @BeforeClass
    public static void setUp() {

        Instrumentation instrumentation = getInstrumentation();
        hmm = new ModuleProxy<HardwareModuleManagement>().getInstance(new HardwareModuleManagementImpl(PolicyManager.getInstance()));
        tm = new ModuleProxy<TerminalBasicFunctionManagement>().getInstance(new TerminalBasicFunctionManagementImpl(PolicyManager.getInstance()));
        // Initialize UiDevice instance
        mDevice = UiDevice.getInstance(getInstrumentation());
        Configurator configurator = Configurator.getInstance();
        //todo 设置等待小组件在用户界面中可见的超时时间
        configurator.setWaitForSelectorTimeout(2000);
        // Start from the home screen
        mDevice.pressHome();
        // TODO: 2024/1/25  启动原app
        luanchOriginApp();
        // TODO: 第一次启动需要授权，否则uiautomator 拿不到权限
        auth();
    }

    public static void luanchOriginApp() {
        // Wait for launcher
        final String launcherPackage = getLauncherPackageName();
        assertThat(launcherPackage, notNullValue());
        Log.i(TAG, "useAppContext: " + launcherPackage);
        mDevice.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)), LAUNCH_TIMEOUT);

        // Launch the blueprint app
        Context context = getApplicationContext();
        Intent intent = context.getPackageManager().getLaunchIntentForPackage(BASIC_SAMPLE_PACKAGE);

        // TODO: 2024/1/25  有时候通过包名获取intent 为null， 需要另外处理
        if (Objects.nonNull(intent)) {
            // Clear out any previous instances
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
        } else {
            intent = new Intent();
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//可选
            ComponentName comp = new ComponentName(BASIC_SAMPLE_PACKAGE, "com.cncytech.uiautomator_demo.MainActivity");
            intent.setComponent(comp);
        }

        context.startActivity(intent);

        // Wait for the app to appear
        mDevice.wait(Until.hasObject(By.pkg(BASIC_SAMPLE_PACKAGE).depth(0)), LAUNCH_TIMEOUT);
    }

    /**
     * Uses package manager to find the package name of the device launcher. Usually this package
     * is "com.android.launcher" but can be different at times. This is a generic solution which
     * works on all platforms.`
     */
    private static String getLauncherPackageName() {
        // Create launcher Intent
        final Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_HOME);

        // Use PackageManager to get the launcher package name
        PackageManager pm = getApplicationContext().getPackageManager();
        ResolveInfo resolveInfo = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
        return resolveInfo.activityInfo.packageName;
    }


    /**
     * 需求：执行cmd命令，且输出信息到控制台
     *
     * @param cmd
     */
    public void execCmd(String cmd) {
        Log.i(TAG, "execCmd: ---execCmd:  " + cmd);
        Process p = null;
        try {
            p = Runtime.getRuntime().exec(cmd);
            // 启用StreamGobbler线程清理错误流和输入流 防止IO阻塞
            new StreamGobbler(p.getErrorStream(), "ERROR").start();
            new StreamGobbler(p.getInputStream(), "INPUT").start();
            p.waitFor();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (p != null && p.exitValue() != 0) {
                p.destroy();
            }
        }
    }

    @AfterClass
    public static void tearDown() {
        //  execCmd("pm clear " + BASIC_SAMPLE_PACKAGE);
    }


    public static void auth() {
        new MainPage(mDevice).authorization();
    }
}